﻿// -------------------------------
// Color Selection Button
// Version 1.1
// -------------------------------
// Author: Thomas Ascher
// eMail: thomasascher@hotmail.com
// -------------------------------

using System;
using System.ComponentModel;
using System.Drawing;
using System.Windows.Forms;

namespace Microsoft.Office.PowerPoint.STAMP.Controls
{
    /// <summary>
    /// A color button for fonts.
    /// </summary>
    public partial class ColorPickerButton : Button
    {
        private string _autoButton = "Automatic";
        private string _moreButton = "More Colors...";
        private bool _buttonPushed;
        private bool _panelVisible;
        private IColorIndicatorDrawer _colorIndicatorDrawer;

        /// <summary>
        /// Occurs when the selected color has been changed.
        /// </summary>
        public event EventHandler<ColorButtonColorChangedEventArgs> Changed;

        /// <summary>
        /// Initializes a new instance of the <see cref="ColorPickerButton"/> class.
        /// </summary>
        public ColorPickerButton()
        {
            InitializeComponent();
            _colorIndicatorDrawer = new FontColorIndicatorDrawer();
        }

        /// <summary>
        /// Gets or sets the text for the automatic button.
        /// </summary>
        [Browsable(true)]
        [DefaultValue("Automatic")]
        public string AutomaticButtonText
        {
            get { return _autoButton; }
            set { _autoButton = value; }
        }

        /// <summary>
        /// Gets or sets the text for the more colors button.
        /// </summary>
        [Browsable(true)]
        [DefaultValue("More Colors...")]
        public string MoreColorsButtonText
        {
            get { return _moreButton; }
            set { _moreButton = value; }
        }

        /// <summary>
        /// Gets or sets the color applied when clicking the automatic button.
        /// </summary>
        public Color AutomaticColor { get; set; }

        /// <summary>
        /// Gets the color indicator drawer.
        /// </summary>
        [Browsable(true)]
        [DefaultValue(ColorIndicatorDrawer.FontIndicator)]
        public ColorIndicatorDrawer ColorIndicatorDrawer
        {
            get
            {
                if (_colorIndicatorDrawer == null)
                    return STAMP.Controls.ColorIndicatorDrawer.Custom;
                Type indicatorType = _colorIndicatorDrawer.GetType();
                if (indicatorType == typeof (FontColorIndicatorDrawer))
                    return STAMP.Controls.ColorIndicatorDrawer.FontIndicator;
                if (indicatorType == typeof (RectangleColorIndicatorDrawer))
                    return STAMP.Controls.ColorIndicatorDrawer.RectangleIndicator;
                return STAMP.Controls.ColorIndicatorDrawer.Custom;
            }
            set
            {
                if (value == ColorIndicatorDrawer.FontIndicator)
                    _colorIndicatorDrawer = new FontColorIndicatorDrawer();
                else if (value == ColorIndicatorDrawer.RectangleIndicator)
                    _colorIndicatorDrawer = new RectangleColorIndicatorDrawer();
                Refresh();
            }
        }

        protected virtual void OnChanged(ColorButtonColorChangedEventArgs e)
        {
            if (Changed != null)
                Changed(this, e);
        }

        protected override void Dispose(bool disposing)
        {
            if (disposing)
            {
                if (_components != null)
                    _components.Dispose();
            }

            base.Dispose(disposing);
        }

        protected override void OnMouseDown(MouseEventArgs e)
        {
            _buttonPushed = true;
            base.OnMouseDown(e);
        }

        protected override void OnPaint(PaintEventArgs e)
        {
            base.OnPaint(e);

            int offset = 0;

            if (_panelVisible || (_buttonPushed &&
                                  RectangleToScreen(ClientRectangle).Contains(Cursor.Position)))
            {
                ControlPaint.DrawButton(e.Graphics, DisplayRectangle, ButtonState.Pushed);
                offset = 1;
            }

            _colorIndicatorDrawer.DrawColorIndicator(offset, DisplayRectangle, e.Graphics, Enabled, ForeColor);

            Rectangle rectangleAroundTriangle = new Rectangle(new Point(DisplayRectangle.Right - 11, DisplayRectangle.Top + 2), new Size(10, DisplayRectangle.Height - 3));
            Point pt = new Point(rectangleAroundTriangle.Left + 3, ((rectangleAroundTriangle.Height + offset) / 2) + 1);
            Pen trianglePen = new Pen(Enabled ? SystemColors.ControlText : SystemColors.GrayText);

            e.Graphics.FillRectangle(new SolidBrush(SystemColors.Control), rectangleAroundTriangle);
            e.Graphics.DrawLine(trianglePen, pt.X, pt.Y - 1, pt.X + 4, pt.Y - 1);
            e.Graphics.DrawLine(trianglePen, pt.X + 1, pt.Y, pt.X + 3, pt.Y);
            e.Graphics.DrawLine(trianglePen, pt.X + 2, pt.Y, pt.X + 2, pt.Y + 1);

        }

        protected override void OnMouseUp(MouseEventArgs e)
        {
            _buttonPushed = false;
            base.OnMouseUp(e);
        }

        protected override void OnClick(EventArgs e)
        {
            _panelVisible = true;
            Refresh();

            Point pt = Parent.PointToScreen(new Point(Left, Bottom));

            ColorButtonSelectionPanel buttonSelectionPanel = new ColorButtonSelectionPanel(pt, MoreColorsButtonText, AutomaticButtonText, ForeColor, Font, AutomaticColor);
            buttonSelectionPanel.Closed += buttonSelectionPanel_Closed;
            buttonSelectionPanel.Show();
        }

        void buttonSelectionPanel_Closed(object sender, EventArgs e)
        {
            _panelVisible = false;
            Color selectedColor = ((ColorButtonSelectionPanel) sender).CurrentColor;
            if (selectedColor != ForeColor)
            {
                ForeColor = selectedColor;
                OnChanged(new ColorButtonColorChangedEventArgs(ForeColor));
                Refresh();
            }
            
        }
    }

    /// <summary>
    /// Contains the newly selected color when the control changes.
    /// </summary>
    public class ColorButtonColorChangedEventArgs : EventArgs
    {
        private readonly Color _selectedColor;

        /// <summary>
        /// Initializes a new instance of the <see cref="ColorButtonColorChangedEventArgs"/> class.
        /// </summary>
        /// <param name="selectedColor">Color of the selected.</param>
        public ColorButtonColorChangedEventArgs(Color selectedColor)
        {
            _selectedColor = selectedColor;
        }

        /// <summary>
        /// Gets the selected color.
        /// </summary>
        public Color SelectedColor
        {
            get { return _selectedColor; }
        }
    }
}
